﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AgendaManager.AgendaService;
using System.IO;
using System.Drawing.Imaging;

namespace AgendaManager
{
    public partial class frmFotos : Form
    {
        public Obra Obra { get; set; }
        public Carpeta Carpeta { get; set; }
        public Semana Semana { get; set; }
        public SubCarpeta SubCarpeta { get; set; }

        List<Foto> Fotos = new List<Foto>();
        Foto ActiveFoto = new Foto();

        //for Test
        private bool test = true;

        public frmFotos()
        {
            InitializeComponent();
        }

        private void frmFotos_Load(object sender, EventArgs e)
        {
            if (SubCarpeta != null)
            {
                pbActivePhoto.BringToFront();
                txObra.Text = Obra.Nombre;
                txSemana.Text = Semana.Nombre;
                txCarpeta.Text = SubCarpeta.Nombre;

                //Fotos = ConnectHelper.ws.RetrieveEntitiesWhere(new Foto(),
                //    SubCarpeta.Id.ToString()).Cast<Foto>().ToList();
                pbNext.Enabled = false;
                pbPrevious.Enabled = false;

                if (Fotos.Count > 0)
                {
                    ActiveFoto = Fotos.First();
                    pbActivePhoto.Image = ScaleImage(Image.FromStream(new MemoryStream(ActiveFoto.Archivo)), 488, 414);
                }

                
                
            }
        }

        public static Image ScaleImage(Image image, int maxWidth, int maxHeight)
        {
            var ratioX = (double)maxWidth / image.Width;
            var ratioY = (double)maxHeight / image.Height;
            var ratio = Math.Min(ratioX, ratioY);

            var newWidth = (int)(image.Width * ratio);
            var newHeight = (int)(image.Height * ratio);

            var newImage = new Bitmap(newWidth, newHeight);
            Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight);
            return newImage;
        }

        internal void SetValues(Obra obra, Carpeta carpeta, Semana semana, SubCarpeta subcarpeta)
        {
            try
            {
                Obra = obra;
                Semana = semana;
                SubCarpeta = subcarpeta;

                txObra.Text = Obra.Nombre;
                txSemana.Text = Semana.Nombre;
                txCarpeta.Text = SubCarpeta.Nombre;
                
                //ActiveFoto.Id = 0;

                bwDownload.RunWorkerAsync();

                //Fotos = ConnectHelper.ws.RetrieveEntitiesWhere(new Foto(),
                //    "SubCarpetaId = " + SubCarpeta.Id.ToString()).Cast<Foto>().ToList();

                //if (Fotos.Count > 0)
                //{
                //    ActiveFoto = Fotos.First();

                //    pbActivePhoto.Image = ScaleImage(Image.FromStream(new MemoryStream(ActiveFoto.Archivo)), 488, 414);    
                //}
                
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// true = next, false = previous
        /// </summary>
        /// <returns></returns>
        private Foto GetPhotoToShow(bool isNext)
        {
            int posicion = Fotos.FindIndex(x => x.Id == ActiveFoto.Id);

            
            
            if (isNext)
            {
                if (Fotos.Count > posicion + 1)
                    return Fotos[++posicion];
                else
                    return Fotos[posicion];
            }
            else 
                if(posicion < 0)
                {
                    return ActiveFoto;
                }
                else
                {
                    if (posicion != 0)
                        return Fotos[--posicion];
                    else
                        return Fotos[posicion];
                }
        }

        private void pbNext_Click(object sender, EventArgs e)
        {
            if (Fotos.Count > 0)
            {
                test = false;
                ActiveFoto = GetPhotoToShow(true);

                pbActivePhoto.Image = ScaleImage(Image.FromStream(new MemoryStream(ActiveFoto.Archivo)), 488, 414);                
            }
        }

        private void pbPrevious_Click(object sender, EventArgs e)
        {
            if (Fotos.Count > 0)
            {
                test = true;
                ActiveFoto = GetPhotoToShow(false);
                if (ActiveFoto.Id != 0)
                    pbActivePhoto.Image = ScaleImage(Image.FromStream(new MemoryStream(ActiveFoto.Archivo)), 488, 414);
            }
        }

        private void btnDownload_Click(object sender, EventArgs e)
        {
            try
            {
                this.saveFileDialog.FileName = ActiveFoto.Nombre;
                this.saveFileDialog.DefaultExt = ActiveFoto.Extension;
                this.saveFileDialog.ShowDialog();
                File.WriteAllBytes(saveFileDialog.FileName, ActiveFoto.Archivo);

                MessageBox.Show("El contenido ha sido descargado correctamente.",
                            "Descarga Contenido.",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);
            }
            catch (Exception)
            {
                MessageBox.Show("Ocurrió un problema al descargar el archivo, por favor intente nuevamente mas tarde.",
                        "Descarga Contenido.",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                throw;
            }
        }

        private void btnDownloadFolder_Click(object sender, EventArgs e)
        {
            try
            {
                using (FolderBrowserDialog fbd = new FolderBrowserDialog())
                {
                    fbd.ShowNewFolderButton = true;
                    string folderPath = string.Empty;
                    if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        folderPath = fbd.SelectedPath;
                        foreach (Foto foto in Fotos)
                        {
                            File.WriteAllBytes(folderPath + @"\" + foto.Nombre, foto.Archivo);
                        }


                        MessageBox.Show("Las fotos se han descargado correctamente.",
                                    "Descarga Contenido.",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);
                    }
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Ocurrió un problema al descargar el archivo, por favor intente nuevamente mas tarde.",
                        "Descarga Contenido.",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                throw;
            }
        }

        private void btnSubirFotos_Click(object sender, EventArgs e)
        {
            List<Foto> fotos = new List<Foto>();
            using (OpenFileDialog opf = new OpenFileDialog())
            {
                opf.Multiselect = true;
                opf.Filter = "Images (*.BMP;*.JPG;*.GIF,*.PNG,*.TIFF)|*.BMP;*.JPG;*.GIF;*.PNG;*.TIFF";

                this.openFileDialog.Title = "Select Photos";

                if (opf.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    foreach (String file in opf.FileNames)
                    {
                        try
                        {
                            Foto f = new Foto();

                            //Image img = ResizeImage(file, 488, 414, true);

                            Image img = GetImageLowQuality(file);
                            
                            ImageConverter converter = new ImageConverter();

                            f.Archivo = (byte[])converter.ConvertTo(img, typeof(byte[]));
                            f.Nombre = file.Substring(file.LastIndexOf("\\") + 1);
                            f.Nombre = f.Nombre.Remove(f.Nombre.LastIndexOf('.'));
                            f.Extension = file.Substring(file.LastIndexOf(".") + 1);
                            f.SubCarpetaId = SubCarpeta.Id;

                            fotos.Add(f);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("Error: " + ex.Message);
                        }
                    }
                }
            }

            if (fotos.Count > 0)
            {
                MessageBox.Show("Se están subiendo las fotos al servidor, puede continuar utilizando el programa pero por favor no cerrarlo hasta que se encuentre Listo.",
                                    "Subiendo Imágenes.",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);

                bwUpload.RunWorkerAsync(fotos);
            }

            //if (fotos.Count > 0)
            //{
            //    using (frmWaiting f = new frmWaiting())
            //    {
            //        f.SetValues(fotos);
            //        if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            //        {
            //            Fotos = ConnectHelper.ws.RetrieveEntitiesWhere(new Foto(),
            //            "SubCarpetaId = " + SubCarpeta.Id.ToString()).Cast<Foto>().ToList();

            //            if (Fotos.Count > 0)
            //            {
            //                ActiveFoto = Fotos.First();

            //                pbActivePhoto.Image = ScaleImage(Image.FromStream(new MemoryStream(ActiveFoto.Archivo)), 488, 414);
            //            }
            //        }
            //    }
            //}
            

            //foreach (Foto f in fotos)
            //{
            //    f.SubCarpetaId = SubCarpeta.Id;
            //    ConnectHelper.ws.NuevaFoto(f);
            //}
        }

        private ImageCodecInfo GetEncoder(ImageFormat format)
        {

            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }

        private Image GetImageLowQuality(string file)
        {
            try
            {
                // Get a bitmap.
                //Bitmap bmp1 = new Bitmap(file);
                Bitmap bmp1 = new Bitmap(ResizeImage(file, 800, 600, false));
                ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);

                // Create an Encoder object based on the GUID 
                // for the Quality parameter category.
                System.Drawing.Imaging.Encoder myEncoder =
                    System.Drawing.Imaging.Encoder.Quality;

                string tempFile = string.Empty;
                // Create an EncoderParameters object. 
                // An EncoderParameters object has an array of EncoderParameter 
                // objects. In this case, there is only one 
                // EncoderParameter object in the array.
                EncoderParameters myEncoderParameters = new EncoderParameters(1);

                EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 60L);
                myEncoderParameters.Param[0] = myEncoderParameter;
                tempFile = Path.GetTempFileName();
                bmp1.Save(tempFile, jgpEncoder, myEncoderParameters);

                Image imagenTuneada = System.Drawing.Image.FromFile(tempFile);
                //System.IO.File.Delete(tempFile);

                return imagenTuneada;
                //myEncoderParameter = new EncoderParameter(myEncoder, 70L);
                //myEncoderParameters.Param[0] = myEncoderParameter;
                //tempFile = Path.GetTempFileName();
                //bmp1.Save(tempFile, jgpEncoder, myEncoderParameters);

                //// Save the bitmap as a JPG file with zero quality level compression.
                //myEncoderParameter = new EncoderParameter(myEncoder, 0L);
                //myEncoderParameters.Param[0] = myEncoderParameter;
                //tempFile = Path.GetTempFileName();
                //bmp1.Save(tempFile, jgpEncoder, myEncoderParameters);
            }
            catch (Exception)
            {
                
                throw;
            }
            
        }

        internal static Image ResizeImage(string OriginalFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider)
        {
            System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFile);

            // Prevent using images internal thumbnail
            FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
            FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);

            if (OnlyResizeIfWider)
            {
                if (FullsizeImage.Width <= NewWidth)
                {
                    NewWidth = FullsizeImage.Width;
                }
            }

            int NewHeight = FullsizeImage.Height * NewWidth / FullsizeImage.Width;
            if (NewHeight > MaxHeight)
            {
                // Resize with height instead
                NewWidth = FullsizeImage.Width * MaxHeight / FullsizeImage.Height;
                NewHeight = MaxHeight;
            }

            System.Drawing.Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero);

            // Clear handle to original file so that we can overwrite it if necessary
            FullsizeImage.Dispose();

            return NewImage;
        }

        private void bWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            ConnectHelper.ws.Timeout = 600000;
            List<Foto> fotos = e.Argument as List<Foto>;
            FormsHelper.ChangeStatusLabel("");
            int i = 1;
            foreach (Foto foto in fotos)
            {
                FormsHelper.ChangeStatusLabel("Subiendo " + i + " de " + Convert.ToInt32(fotos.Count) + " fotos.");
                ConnectHelper.ws.NuevaFoto(foto);
                i++;
            }

        }

        private void bWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            FormsHelper.ChangeStatusLabel("Listo.");
        }

        private void bwDownload_DoWork(object sender, DoWorkEventArgs e)
        {
            ConnectHelper.ws.Timeout = 600000;
            int i = 1;
            int max = ConnectHelper.ws.GetMax(new Foto());
            FormsHelper.ChangeStatusLabel("Descargando fotografias...");
            
            while (i <= max)
            {
                List<Foto> f = ConnectHelper.ws.GetEntitiesPaginated(new Foto(), i, "SubCarpetaId = " + SubCarpeta.Id.ToString()).Cast<Foto>().ToList();
                if (f != null && f.Count > 0)
                    Fotos.AddRange(f);
                i += 10;
            }
        }

        private void bwDownload_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            FormsHelper.ChangeStatusLabel("Listo.");
        }
    }
}
